package com.duapk.search.work;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.duapk.nlp.bean.QueryParam;
import com.duapk.nlp.bean.RewriteField;
import com.duapk.nlp.bean.RewriteResult;
import com.duapk.nlp.constant.WordType;
import com.duapk.nlp.query.QueryResource;
import com.duapk.nlp.query.QueryRewriter;
import com.duapk.search.conf.ConfigFactory;
import com.duapk.search.constant.Constant;

/**
 * 查询重写代理类
 * 
 * @Package: com.duapk.search.work
 * @ClassName: RewriterProxy
 * @author: jiangzheng
 * @date: Apr 4, 2011 9:26:50 PM
 * 
 */
public class RewriterProxy {

	private static Logger logger = LoggerFactory.getLogger(RewriterProxy.class);

	private static RewriterProxy instance;

	private static byte[] lock = new byte[0];

	private QueryRewriter rewriter;

	private QueryParam param;

	private List<RewriteField> contentFields;

	private RewriterProxy() {
		init();
	}

	public static RewriterProxy getInstance() {
		if (instance == null) {
			synchronized (lock) {
				if (instance == null) {
					instance = new RewriterProxy();
				}
			}
		}
		return instance;
	}

	private void init() {
		rewriter = initQueryRewriter();
		contentFields = loadFieldConfig();
		param = loadParamConfig();
	}

	/**
	 * 初始化查询重写对象
	 * 
	 * @Title: initQueryRewriter
	 * @author: jiangzheng
	 * @date: Apr 4, 2011 9:30:48 PM
	 * @return
	 */
	private QueryRewriter initQueryRewriter() {
		QueryRewriter rewriter = null;
		try {
			QueryResource resource = QueryResource.getInstance();
			rewriter = new ApkQueryRewriter(resource);
		} catch (IOException e) {
			logger.error("Fatal error: fail to create QueryRewriter.", e);
		}
		return rewriter;
	}

	/**
	 * 加载查询重写参数配置
	 * 
	 * @Title: loadParamConfig
	 * @author: jiangzheng
	 * @date: Apr 4, 2011 9:35:00 PM
	 * @return
	 */
	private QueryParam loadParamConfig() {
		QueryParam param = new QueryParam();
		param.put(WordType.ABBREVATION, true);
		param.put(WordType.LETTER, true);
		param.put(WordType.SP_WORD, true);
		param.put(WordType.SINGLE_WORD, true);
		param.put(WordType.NORMAL_WORD, true);
		param.put(WordType.DIGIT, true);
		param.put(WordType.LETTER_AND_DIGIT, true);

		param.put(WordType.SP_WORD, ConfigFactory
				.getFloat("Rewriter.queryParam.spWeight"));
		param.put(WordType.NORMAL_WORD, ConfigFactory
				.getFloat("Rewriter.queryParam.normalWeight"));

		param.put(WordType.SINGLE_WORD, ConfigFactory
				.getFloat("Rewriter.queryParam.singleWordWeight"));
		param.put(WordType.ABBREVATION, ConfigFactory
				.getFloat("Rewriter.queryParam.abbrevationWeight"));
		param.put(WordType.LETTER_AND_DIGIT, ConfigFactory
				.getFloat("Rewriter.queryParam.letterOrDightWeight"));
		param.put(WordType.LETTER, ConfigFactory
				.getFloat("Rewriter.queryParam.letterOrDightWeight"));
		param.put(WordType.DIGIT, ConfigFactory
				.getFloat("Rewriter.queryParam.letterOrDightWeight"));
		param.put(WordType.CORRECT, ConfigFactory
				.getFloat("Rewriter.queryParam.correctedWeight"));
		param.put(WordType.SYNONYM, ConfigFactory
				.getFloat("Rewriter.queryParam.synonymWeight"));
		param.put(WordType.OTHER, ConfigFactory
				.getFloat("Rewriter.queryParam.otherWeight"));
		return param;
	}

	/**
	 * 加载查询重写字段配置
	 * 
	 * @Title: loadFieldConfig
	 * @author: jiangzheng
	 * @date: Apr 4, 2011 9:39:34 PM
	 * @return
	 */
	private List<RewriteField> loadFieldConfig() {
		List<RewriteField> contentFields = new ArrayList<RewriteField>();
		List<String> fieldNames = ConfigFactory
				.getList("Rewriter.contentFields.field[@name]");
		int index = 0;
		for (String fieldName : fieldNames) {
			RewriteField rewriteField = new RewriteField(fieldName);
			rewriteField.setBoost(ConfigFactory
					.getFloat("Rewriter.contentFields.field(" + index
							+ ")[@boost]"));
			contentFields.add(rewriteField);
			index++;
		}
		return contentFields;
	}

	/**
	 * 进行查询重写
	 * 
	 * @Title: rewrite
	 * @author: jiangzheng
	 * @date: Jun 9, 2011 2:49:13 PM
	 * @param keyword
	 *            搜索关键词
	 * @param field
	 *            搜索字段，为空则默认搜索所有可搜索字段
	 * @param fieldWeight
	 *            该字段的权重
	 * @return
	 */
	public RewriteResult rewrite(String keyword, String field, float fieldWeight) {
		if (field != null && !field.isEmpty() && !Constant.ALL.equals(field)) {
			List<RewriteField> contentFields = new ArrayList<RewriteField>();
			contentFields.add(new RewriteField(field, fieldWeight));
			return rewriter.rewrite(keyword, param, contentFields, false);
		}
		return rewriter.rewrite(keyword, param, contentFields, false);
	}
}
